package evan.curtis.beersnob;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Iterator;

import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import evan.curtis.beersnob.util.Constants;
import evan.curtis.beersnob.util.DatabaseFunctions;
import evan.curtis.beersnob.util.DialogViewPair;
import evan.curtis.beersnob.util.UIFunctions;
import evan.curtis.beersnob.util.Vibration;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnLongClickListener;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;

public class BeerView extends Activity {

	private ImageView img;
	private JSONArray databaseValues;
	private LinearLayout reviewsLayout;

	private TextView t1;
	private TextView t2;
	private TextView t3;
	private TextView t4;

	private String name;
	private int id;

	// ------------------------------------------------------------------------------------/

	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		this.setContentView(R.layout.beer_view);

		Intent intent = getIntent();
		id = intent.getIntExtra("id", 0);
		name = intent.getStringExtra("name");
		String brewery = intent.getStringExtra("brewer");
		String style = intent.getStringExtra("style");
		int rating = intent.getIntExtra("rating", 0);

		// initialize views
		t1 = (TextView) findViewById(R.id.nameLabel);
		t2 = (TextView) findViewById(R.id.brewerLabel);
		t3 = (TextView) findViewById(R.id.styleLabel);
		t4 = (TextView) findViewById(R.id.ratingLabel);
		img = (ImageView) findViewById(R.id.beerLabel);
		reviewsLayout = (LinearLayout) findViewById(R.id.reviewLayout);

		t1.setText(name);
		t2.setText(brewery);
		t3.setText(style);
		t4.setText(Integer.toString(rating));

		// get an image for the imageView
		new GetImageURL().execute(brewery + " " + name);

		// get reviews
		new ReviewLoader().execute(Integer.toString(id));

	}

	// ------------------------------------------------------------------------------------/

	public boolean onCreateOptionsMenu(Menu menu) {
		MenuInflater inflater = getMenuInflater();
		inflater.inflate(R.layout.beer_view_menu_layout, menu);
		return true;
	}

	// ------------------------------------------------------------------------------------/

	public boolean onOptionsItemSelected(MenuItem item) {

		switch (item.getItemId()) {

		case R.id.addReview:
			showReviewDialog();

		default:
			return super.onOptionsItemSelected(item);
		}
	}

	// ------------------------------------------------------------------------------------/

	private void showReviewDialog() {

		DialogViewPair pair = UIFunctions.createAlertDialog(this, "Add Review",
				R.layout.add_review_layout);
		final AlertDialog dialog = pair.a;
		View volumeView = pair.v;

		final EditText ratingField = (EditText) volumeView
				.findViewById(R.id.rating);
		final EditText commentField = (EditText) volumeView
				.findViewById(R.id.comment);

		dialog.setButton(DialogInterface.BUTTON_NEUTRAL, "OK",
				new DialogInterface.OnClickListener() {

					public void onClick(DialogInterface arg0, int arg1) {

						String name = t1.getText().toString();
						String user = Constants.USER_NAME;
						String rating = ratingField.getText().toString();
						String comment = commentField.getText().toString();

						new DatabaseInsert().execute(Constants.INSERT_REVIEW,
								name, user, rating, comment);
						Log.i("database", "dialog clicked");
						dialog.cancel();

					}
				});

		dialog.show();

	}

	// ------------------------------------------------------------------------------------/

	private void updateReviews() throws JSONException {

		// remove all views from the review layout, then get reviews from
		// database and add them
		reviewsLayout.removeAllViews();

		// check if there are no results
		if (databaseValues.length() == 0) {
			TextView t = new TextView(this);
			t.setText("No reviews.");
			reviewsLayout.addView(t);
		}

		// if there are results, print them
		for (int i = 0; i < databaseValues.length(); i++) {
			JSONObject json_data = databaseValues.getJSONObject(i);

			final String user = json_data.getString("user");
			final String rating = json_data.getString("rating");
			final String comment = json_data.getString("comment");

			// inflate layout to display results
			RelativeLayout rl = new RelativeLayout(this);
			LayoutInflater inflater = (LayoutInflater) this
					.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

			View volumeView = inflater.inflate(R.layout.review_card, rl);

			// initialize TextViews
			TextView userView = (TextView) volumeView.findViewById(R.id.userName);
			TextView ratingView = (TextView) volumeView.findViewById(R.id.rating);
			TextView commentView = (TextView) volumeView.findViewById(R.id.comment);
			
			userView.setText(user);
			ratingView.setText(rating);
			commentView.setText(comment);

			reviewsLayout.addView(volumeView);

		}
	}

	private void updateTextViews(JSONArray jArray) {

		try {
			JSONObject jObj = jArray.getJSONObject(0);
			int rating = jObj.getInt("avg_rating");
			t4.setText(Integer.toString(rating));

			Log.i("length", Integer.toString(jArray.length()));
			Log.i("refresh", Integer.toString(rating));

		} catch (JSONException e) {
			e.printStackTrace();
		}

		new ReviewLoader().execute(Integer.toString(id));
	}

	// ------------------------------------------------------------------------------------/

	private void updateImage(Drawable d) {
		img.setImageDrawable(d);

	}

	// ------------------------------------------------------------------------------------/

	private JSONObject getBeerLabelUrl(String name) throws IOException,
			JSONException {

		String encodedName = URLEncoder.encode(name);
		Log.i("encode", encodedName);
		URL url = new URL(
				"https://ajax.googleapis.com/ajax/services/search/images?"
						+ "v=1.0&q=" + encodedName + "&userip=INSERT-USER-IP");
		URLConnection connection = url.openConnection();
		// connection.addRequestProperty("Referer", "");

		String line;
		StringBuilder builder = new StringBuilder();
		BufferedReader reader = new BufferedReader(new InputStreamReader(
				connection.getInputStream()));
		while ((line = reader.readLine()) != null) {
			builder.append(line);
		}

		JSONObject json = new JSONObject(builder.toString());

		return json;
	}

	// ------------------------------------------------------------------------------------/

	private class GetImageURL extends AsyncTask<String, Void, String> {

		JSONObject imgUrl;

		@Override
		protected String doInBackground(String... params) {

			try {
				imgUrl = getBeerLabelUrl(params[0]);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (JSONException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			return null;
		}

		@Override
		protected void onPostExecute(String result) {

			try {
				JSONObject responseData = imgUrl.getJSONObject("responseData");
				JSONArray results = responseData.getJSONArray("results");
				JSONObject firstResult = (JSONObject) results.get(0);

				String url = firstResult.getString("url");
				Log.i("url", url);
				new ImageLoader().execute(url);

			} catch (JSONException e) {
				Log.i("jsonarray", "fail");
				e.printStackTrace();
			}

		}
	}

	// ------------------------------------------------------------------------------------/

	private class ImageLoader extends AsyncTask<String, Void, String> {

		Drawable d = null;

		@Override
		protected String doInBackground(String... params) {
			String url = params[0];
			try {
				d = Drawable.createFromStream(
						((java.io.InputStream) new java.net.URL(url)
								.getContent()), "");

			} catch (MalformedURLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			return null;
		}

		@Override
		protected void onPostExecute(String result) {
			updateImage(d);
		}

	}

	// ------------------------------------------------------------------------------------/

	private class ReviewLoader extends AsyncTask<String, Void, String> {

		
		JSONArray returnValue = null;

		@Override
		protected String doInBackground(String... params) {

			String value = params[0];
			String id = null;
			try {
				id = URLEncoder.encode(value, "UTF-8");
			} catch (UnsupportedEncodingException e) {

				e.printStackTrace();
			}
			
		
			returnValue = DatabaseFunctions.getJSONArray(Constants.GET_REVIEWS, "?id=" + id);
			return null;

		}

		@Override
		protected void onPostExecute(String result) {

			databaseValues = returnValue;
			try {
				updateReviews();
			} catch (JSONException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

		}

		@Override
		protected void onPreExecute() {
			
		}

		@Override
		protected void onProgressUpdate(Void... values) {

		}
	}

	// ------------------------------------------------------------------------------------/

	private class DatabaseInsert extends AsyncTask<String, Void, String> {

		String filename;

		@Override
		protected String doInBackground(String... params) {

			filename = params[0];

			if (filename.equals(Constants.INSERT_REVIEW)) {
				String name = null;
				String user = null;
				String rating = null;
				String comment = null;

				// encode all parameters to url format
				try {
					name = URLEncoder.encode(params[1], "UTF-8");
					user = URLEncoder.encode(params[2], "UTF-8");
					rating = URLEncoder.encode(params[3], "UTF-8");
					comment = URLEncoder.encode(params[4], "UTF-8");

				} catch (UnsupportedEncodingException e) {
					e.printStackTrace();
				}

				String query = "?name=" + name + "&user=" + user + "&rating="
						+ rating + "&comment=" + comment;

				InputStream is = null;
				ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();

				// http post
				try {
					HttpClient httpclient = new DefaultHttpClient();
					HttpPost httppost = new HttpPost(
							"http://24.112.144.68:256/" + filename + query);
					httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
					HttpResponse response = httpclient.execute(httppost);
					HttpEntity entity = response.getEntity();
					is = entity.getContent();
				} catch (Exception e) {
					Log.e("log_tag", "Error in http connection " + e.toString());
				}

			}

			new RefreshTextViews().execute(Integer.toString(id));
			return filename;
		}
	}

	private class RefreshTextViews extends AsyncTask<String, Void, String> {

		JSONArray returnValue;

		@Override
		protected String doInBackground(String... params) {
			String query = null;
			try {
				query = "?id=" + URLEncoder.encode(params[0], "UTF-8");
			} catch (UnsupportedEncodingException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			returnValue = DatabaseFunctions.getJSONArray(
					Constants.SEARCH_BY_ID, query);
			return null;
		}

		protected void onPostExecute(String result) {
			updateTextViews(returnValue);

		}

	}

	// ------------------------------------------------------------------------------------/

	

}
